package com.sk.rpcAssistNetty.policy;



import com.sk.rpcAssistNetty.consumerAssist.ConsumerAssistStrategyContent;
import com.sk.rpcAssistNetty.io.netty.RpcRequest;
import com.sk.rpcAssistNetty.io.netty.client.IdWorker;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * 动态代理，需要注意的是，这里用到的是JDK自带的动态代理，代理对象只能是接口，不能是类
 * @author 孙文斌
 */

@Data
@Slf4j
public class ServiceProxy<T> implements InvocationHandler{

    private Class<T> interfaceType;
    private ConsumerAssistStrategyContent consumerAssistStrategyContent;

    private IdWorker idWorker;
    private final  String SNOWFLAKE_WORKERID = "snowflake.workerid";
    private final  String SNOWFLAKE_DATACENTERID = "snowflake.datacenterid";
    private final  String SNOWFLAKE_SEQUENCE = "snowflake.sequence";


    public ServiceProxy(Class<T> interfaceType) {
        this.interfaceType = interfaceType;
        this.consumerAssistStrategyContent = initConsumerAssistStrategyContent();
    }

    private ConsumerAssistStrategyContent initConsumerAssistStrategyContent() {
        return ConsumerAssistStrategyContent.getInstance();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this,args);
        }
        RpcRequest rpcRequest = method2RpcRequest(method,args);
        //生成全局唯一的请求id
        generateRequestId(rpcRequest);
        return consumerAssistStrategyContent.invoke(rpcRequest);
    }

    private synchronized void generateRequestId(RpcRequest rpcRequest) {
        if(idWorker==null){
            YamlPropertiesFactoryBean yamlMapFactoryBean = new YamlPropertiesFactoryBean(); //可以加载多个yml文件
            yamlMapFactoryBean.setResources(new ClassPathResource("application.yml"));
            Properties properties = yamlMapFactoryBean.getObject(); //获取yml里的参数
            long workerId = Long.valueOf(properties.getProperty(SNOWFLAKE_WORKERID));
            long datacenterId = Long.valueOf(properties.getProperty(SNOWFLAKE_DATACENTERID));
            long sequence = Long.valueOf(properties.getProperty(SNOWFLAKE_SEQUENCE));
            this.idWorker = new IdWorker(workerId,datacenterId,sequence);
        }
        rpcRequest.setRequestId(String.valueOf(idWorker.nextId()));
    }

    private RpcRequest method2RpcRequest(Method method, Object[] args) {
        RpcRequest rpcRequest = new RpcRequest();
        rpcRequest.setClassName(method.getDeclaringClass().getName());
        rpcRequest.setMethodName(method.getName());
        rpcRequest.setArguments(args);
        rpcRequest.setParameterTypes(method.getParameterTypes());
        return rpcRequest;
    }
}